package suites.page {
	import suites.AbstractConfig;
	import suites.stub.InjectorStub;
	import suites.stub.PageStub;

	import org.flexunit.asserts.assertEquals;
	import org.flexunit.asserts.assertNotNull;
	import org.flexunit.asserts.assertTrue;
	import org.splink.deepsplink.boot.Bootstrapper;
	import org.splink.deepsplink.boot.IDeepsplinkFacade;
	import org.splink.deepsplink.config.ConfigData;
	import org.splink.deepsplink.config.ConfigDataReader;
	import org.splink.deepsplink.navigation.command.INavigationCommand;
	import org.splink.deepsplink.page.IPage;
	import org.splink.deepsplink.page.IPageInternal;
	import org.splink.deepsplink.page.PageFactory;
	import org.splink.deepsplink.page.state.PageState;
	import org.splink.library.tree.INode;
	import org.splink.library.tree.Tree;

	import flash.display.DisplayObject;

	/**
	 * @author Max Kugland
	 */
	public class PageFactoryTest extends AbstractConfig {
		private var _factory : PageFactory;
		private var _cmd : INavigationCommand;
		private var _tree : Tree;

		[Before]
		public function createFacory() : void {
			var config : ConfigData = new ConfigDataReader(standardXml).read();
			new Bootstrapper(config, createBootStrategy(function(facade : IDeepsplinkFacade):void {
				_tree = facade.tree;
				_cmd = facade.navigationCommand;
				_factory = new PageFactory(_tree, new Tree(Tree.clone(_tree.root)), facade);
			}, 0));
			
		}

		[After]
		public function removeFactory() : void {
			_tree.finalize();
			_tree = null;
			_factory = null;
			_cmd = null;
		}

		[Test]
		public function instantiate() : void {
			var a : Array = _tree.toArray();
			assertTrue(a.length > 1);
			for each (var node : INode in a) {
				var page : IPageInternal = _factory.createPage(node.id);
				assertNotNull(page);
				assertEquals(node.id, page.id);
				assertEquals(_cmd, page.navigationCommand);
				assertEquals(PageState.INSTANTIATED_STATE, page.state);
				assertNotNull(page.display);				assertTrue(page.display is DisplayObject);
				assertEquals(0, page.params.length);
				assertEquals(AbstractConfig.PAGE_TITLE + node.id, page.title);
			}
		}
		
		[Test]
		public function inject() : void {
			var count : uint = 0;
			_factory.addInjector(new InjectorStub(function(page : IPage):void {
				if(page is PageStub) {
					count++;	
				}
			}));
			
			var a : Array = _tree.toArray();
			assertTrue(a.length > 1);
			for each (var node : INode in a) {
				_factory.createPage(node.id);
			}

			assertEquals(count, a.length);
		}
		
		[Test]
		public function multiInject() : void {
			var count : uint = 0;
			_factory.addInjector(new InjectorStub(function(page : IPage):void {
				if(page is PageStub) {
					count++;	
				}
			}));
			_factory.addInjector(new InjectorStub(function(page : IPage):void {
				if(page is PageStub) {
					count++;	
				}
			}));
						
			var a : Array = _tree.toArray();
			assertTrue(a.length > 1);
			for each (var node : INode in a) {
				_factory.createPage(node.id);
			}

			assertEquals(count, a.length * 2);
		}
	}
}